#include "system/profiler.h"

namespace dw {
	namespace system {

std::string Profiler::ToString()
{
	std::stringstream ss;
	ProfileIterator i;
	unsigned nameWidth = 0, 
		currentTimeWidth = 0,
		minTimeWidth = 0, 
		maxTimeWidth = 0, 
		avgTimeWidth = 0, 
		totalTimeWidth = 0, 
		numCallWidth = 0,
		totalWidth = 0;
	
	ss.setf(std::ios::fixed, std::ios::floatfield);
	for (ProfileIterator i = _profiles.begin(); i != _profiles.end(); ++i)
	{
		Profile* profile = i->second;
		std::string str;
		
		nameWidth = (unsigned)profile->_name.size() > nameWidth ? (unsigned)profile->_name.size() : nameWidth;
		str = system::ToString(profile->_currentTime);
		currentTimeWidth = (unsigned)str.size() > currentTimeWidth ? (unsigned)str.size() : currentTimeWidth;
		str = system::ToString(profile->_minTime);
		minTimeWidth = (unsigned)str.size() > minTimeWidth ? (unsigned)str.size() : minTimeWidth;
		str = system::ToString(profile->_maxTime);
		maxTimeWidth = (unsigned)str.size() > maxTimeWidth ? (unsigned)str.size() : maxTimeWidth;
		str = system::ToString(profile->AvgTime());
		avgTimeWidth = (unsigned)str.size() > avgTimeWidth ? (unsigned)str.size() : avgTimeWidth;
		str = system::ToString(profile->_totalTime);
		totalTimeWidth = (unsigned)str.size() > totalTimeWidth ? (unsigned)str.size() : totalTimeWidth;
		str = system::ToString(profile->_numCall);
		numCallWidth = (unsigned)str.size() > numCallWidth ? (unsigned)str.size() : numCallWidth;
	}
	totalWidth = nameWidth + currentTimeWidth + minTimeWidth + maxTimeWidth + avgTimeWidth + totalTimeWidth + numCallWidth;
	
	for (unsigned i = 0; i < totalWidth + 3 * 7; ++i)
		ss << "-";
	ss << "\n";
	
	ss << std::setw(nameWidth) << std::left << "Name" << " | "
		<< std::setw(currentTimeWidth) << "Time" << " | "
		<< std::setw(minTimeWidth) << "Min" << " | "
		<< std::setw(maxTimeWidth) << "Max" << " | "
		<< std::setw(avgTimeWidth) << "Avg" << " | "
		<< std::setw(totalTimeWidth) << "Total" << " | "
		<< std::setw(numCallWidth) << "Calls"
		<< "\n";
	
	for (unsigned i = 0; i < totalWidth + 3 * 7; ++i)
		ss << "-";
	ss << "\n";
	
	for (ProfileIterator i = _profiles.begin(); i != _profiles.end(); ++i)
	{
		Profile* profile = i->second;

		ss << std::setw(nameWidth) << std::left << profile->_name << " | "
			<< std::right << std::fixed << std::setprecision(2)
			<< std::setw(currentTimeWidth) << profile->_currentTime << " | "
			<< std::setw(minTimeWidth) << profile->_minTime << " | "
			<< std::setw(maxTimeWidth) << profile->_maxTime << " | "
			<< std::setw(avgTimeWidth) << profile->AvgTime()<< " | "
			<< std::setw(totalTimeWidth) << profile->_totalTime << " | "
			<< std::setw(numCallWidth) << profile->_numCall
			<< "\n";
	}
	ss << std::flush;
	ss.setf(std::ios::scientific, std::ios::floatfield);
	return ss.str();
}

	}
}

